package com.sikulifang.frequency.utils;

import com.sikulifang.frequency.service.BlockFunction;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * ClassName FrequencyUtil
 * Description
 *
 * @author Yat
 * Date 2023年7月20日, 0020 9:19
 * version 1.0
 */
@Slf4j
public class FrequencyUtil {

    public static final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);


    /**
     * 休眠一段时间
     *
     * @param duration 时间 （毫秒）
     */
    @SuppressWarnings("all")
    public static void rest(Long duration) {
        if (duration != null && duration > 0) {
            Thread thread = Thread.currentThread();
            executor.schedule(() -> LockSupport.unpark(thread), duration, TimeUnit.MILLISECONDS);

            LockSupport.park();

            // long startTime = System.currentTimeMillis();
            // long elapsedTime;
            // do {
            //     elapsedTime = System.currentTimeMillis() - startTime;
            // } while (elapsedTime <= duration);
        }
    }

    /**
     * Description: 暂停
     * <p>
     * Date: 2023年7月18日, 0018 14:09
     *
     * @param function 阻塞线程的条件
     * @param delay    休眠的时间 ms
     */
    public static void suspend(BlockFunction function, Long delay) {
        boolean blockingThreads = function.blockingThreads();
        if (delay != null && blockingThreads) {
            if (delay <= 0) {
                log.error("---------------暂停时间不能小于0------------");
                return;
            }

            rest(delay);

            suspend(function, delay);
        }
    }

    /**
     * Description: 获取锁
     * <p>
     * Date: 2023年7月19日, 0019 16:46
     *
     * @param semaphore   计数信号量
     * @param waitingTime 获取锁的最大等待时间，为空，会一直尝试获取
     */
    public static void acquire(Semaphore semaphore, Long waitingTime) throws InterruptedException {
        // 判断是否需要进行超时等待
        if (waitingTime != null && waitingTime > 0) {
            boolean tryAcquire = semaphore.tryAcquire(waitingTime, TimeUnit.MILLISECONDS);
            if (!tryAcquire) {
                // 获取锁失败
                throw new InterruptedException();
            }

        } else {
            semaphore.acquire();
        }
    }

}
